package com.basics.common.user;


import com.basics.common.exception.CustomException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Objects;

@Component
public class BillLockUtil {
    private static final String BILL_LOCK = "billLock";
    private static final String SEPARATOR = ":";
    private static final String LOCK_STATUS_1 = "1";
    @Autowired
    private StringRedisTemplate redisTemplate;
    private DefaultRedisScript<String> redisScript;

    public BillLockUtil() {
    }

    @PostConstruct
    public void initRedisScript() {
        this.redisScript = new DefaultRedisScript();
        this.redisScript.setResultType(String.class);
        this.redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("luascript/billlock.lua")));
    }

    public boolean lock(String businessCode, String businessId, Long seconds) {
        if (Objects.isNull(seconds)) {
            seconds = 30L;
        }

        String cacheKey = this.getCacheKey(businessCode, businessId);
        String result = (String)this.redisTemplate.execute(this.redisScript, Arrays.asList(cacheKey), new Object[]{seconds.toString(), "1"});
        if (Objects.isNull(result)) {
            return false;
        } else {
            return Objects.equals("1", result);
        }
    }

    private String getCacheKey(String businessCode, String businessId) {
        if (StringUtils.isEmpty(businessCode)) {
            throw new CustomException("获取单据锁key失败：业务code为空");
        } else if (StringUtils.isEmpty(businessId)) {
            throw new CustomException("获取单据锁key失败：业务id为空");
        } else {
            StringBuilder cacheKey = new StringBuilder();
            cacheKey.append("billLock").append(":").append(":").append(businessCode).append(":").append(businessId);
            return cacheKey.toString();
        }
    }

    public void unLock(String businessCode, String businessId) {
        String cacheKey = this.getCacheKey(businessCode, businessId);
        this.redisTemplate.delete(cacheKey);
    }

    public String getLockStatus(String businessCode, String businessId) {
        String cacheKey = this.getCacheKey(businessCode, businessId);
        return (String)this.redisTemplate.opsForValue().get(cacheKey);
    }
}

